using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

namespace MvcToolbox
{
    /// <summary>
    /// Cache Manager Singleton
    /// </summary>
    public class RequestCacheManager
    {
        /// <summary>
        /// The instance
        /// </summary>
        private static RequestCache instance = null;

        /// <summary>
        /// Gets the instance of requestCache.
        /// </summary>
        /// <value>The instance of requestCache.</value>
        public static RequestCache Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new RequestCache();
                }

                return instance;
            }
        }
    }

    /// <summary>
    /// Request Cache Manager
    /// </summary>
    public class RequestCache
    {
     
        /// <summary>
        /// Retrieve the object in cache
        /// Is object doesn't exist in httpContext items or is obsolete, getItemCallback method is called to fill the object
        /// </summary>
        /// <typeparam name="T">Object Type to put or get in httpContext items</typeparam>
        /// <param name="httpContext">Http Context</param>
        /// <param name="cacheId">Object identifier in httpContext items - Must be unique</param>
        /// <param name="getItemCallback">Callback method to fill the object</param>
        /// <returns>Object put in cache</returns>
        public T Get<T>(HttpContextBase httpContext, string cacheId, Func<T> getItemCallback) where T : class
        {
            T item = httpContext.Items[cacheId] as T;
            if (item == null)
            {
                item = getItemCallback();
                httpContext.Items.Add(cacheId, item);
            }

            return item;
        }

        /// <summary>
        /// Retrieve the object in httpContext items
        /// Is object doesn't exist in httpContext items or is obsolete, getItemCallback method is called to fill the object
        /// </summary>
        /// <typeparam name="T">Object Type to put or get in httpContext items</typeparam>
        /// <param name="httpContext">Http Context</param>
        /// <param name="cacheId">Object identifier in httpContext items - Must be unique</param>
        /// <returns>Object put in cache</returns>
        public T Retrieve<T>(HttpContextBase httpContext, string cacheId) where T : class
        {
            T item = httpContext.Items[cacheId] as T;
            if (item == null)
            {
                return null;
            }

            return item;
        }

        /// <summary>
        /// Delete an object using his unique id
        /// </summary>
        /// <param name="httpContext">Http Context</param>
        /// <param name="cacheId">Object identifier in httpContext items</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
        public bool Clear(HttpContextBase httpContext, string cacheId)
        {
            if (httpContext.Items.Contains(cacheId))
            {
                var item = httpContext.Items[cacheId];
                if (item != null)
                {
                    httpContext.Items.Remove(item);
                    return true;
                }
            }

            return false;
        }

        /// <summary>
        /// Delete all object in cache
        /// </summary>
        /// <param name="httpContext">Http Context</param>
        public void ClearAll(HttpContextBase httpContext)
        {
            httpContext.Items.Clear();
        }
    }
}
